home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / FILER / TARSRC.SPK / c / tar < prev    next >
Text File  |  1994-09-13  |  9KB  |  381 lines

  1.  
  2. /* Tape Archive Programme */
  3.  
  4. #include <signal.h>
  5.  
  6. #include "tar.h"
  7. #include "args.h"
  8. #include "options.h"
  9. #include "perms.h"
  10. #include "dir.h"
  11. #include "rmt.h"
  12. #include "tapeio.h"
  13. #include "replace.h"
  14. #include "table.h"
  15. #include "extract.h"
  16.  
  17. static char *version = "[1.2b] (" __DATE__ ")";
  18.  
  19. int CreateArchive;
  20. int ArchiveFileSpecified;
  21. int IgnoreArchiveErrors;
  22. int DoNotExtractFileDates;
  23. int UseListFile;
  24. int ConvertExclamationMark;
  25. int AppendToArchive;
  26. int SwapExtensionToDir;
  27. int ListArchivesContents;
  28. int Verbose;
  29. int ConfirmActions;
  30. int ExtractFromArchive;
  31. int CompressFiles;
  32. int Reblock;
  33. int PeriodSlashConversion;
  34. int FormatFloppies;
  35. int MultipleVolumes;
  36. int GNUmultipleVolumes;
  37. int NoDiskDestroyConfirmation;
  38. int QuietExecution;
  39. int SwapInWholePath;
  40. int CommaFileTypes;
  41. int UnixArchive;
  42. int VeryVerbose;
  43. int AddFileTypeExtension;
  44. int ConvertCompressExtension;
  45. int UseCanonicalisedPaths;
  46. int MaxLeafLength = ADFS_MAXLEAFLENGTH;
  47.  
  48. int tarFileType;
  49.  
  50. int MaxExtLength = 3;
  51. tapedevice_t tapedevice;
  52. int driveno;
  53. char format = 'E';
  54.  
  55. char *listfile = "!tarlist";
  56. char *ArchiveName;
  57. int ArchiveOpen;
  58. FILE *ArchiveFD;
  59. int rmt_fd;
  60.  
  61. int UserInterrupt;
  62.  
  63. Block_t *TmpBlock;
  64. Block_t Block;
  65.  
  66. int NumBlocksRead;
  67. int nblock=20;
  68. int recno;
  69. int first;
  70. int DiscNo=1;
  71. int compression;
  72.  
  73. int isArchie;
  74.  
  75. #if WITH_PWD
  76. int InitialUnset;
  77.  
  78. char InitialPreviousDir[MAXPATHLEN];
  79. char InitialCurrentDir[MAXPATHLEN];
  80. #endif
  81.  
  82. char ScrapName[MAXPATHLEN];
  83. char ScrapNameZ[MAXPATHLEN];
  84.  
  85. char CompressTemplate[MAXPATHLEN];
  86. char DecompressTemplate[MAXPATHLEN];
  87. char CompressExt[256];
  88.  
  89. static int ArchiveIsStdIO;
  90. static int GotInitialDirectories = 0;
  91.  
  92.  
  93. void Terminate(int n) {
  94.   if (GotInitialDirectories) {
  95. #if WITH_PWD
  96.     if (InitialUnset) {
  97.       os_cli("nodir");
  98.     } else {
  99.       ChangeCurrentDir(InitialPreviousDir);
  100.       ChangeCurrentDir(InitialCurrentDir);
  101.     }
  102. #endif
  103.   }
  104.   switch (tapedevice) {
  105.     case tapedevice_FILE:
  106.       if (ArchiveOpen) {
  107.         fclose(ArchiveFD);
  108.         if (AppendToArchive && !ArchiveIsStdIO) {
  109.           SetFileType(ArchiveName, tarFileType);
  110.         }
  111.       }
  112.       break;
  113.     case tapedevice_RMT:
  114.       if (ArchiveOpen) {
  115.         rmtclose(rmt_fd);
  116.       }
  117.       break;
  118.   }
  119.   exit(n);
  120. } /* Terminate */
  121.  
  122.  
  123. char Decision(char default_answer) {
  124.   char c;
  125.  
  126.   c = getchar();
  127.   if (c != '\n')
  128.     while (getchar() != '\n')
  129.       ;
  130.   else
  131.     c = default_answer;
  132.   return (c);
  133. } /* Decision */
  134.  
  135.  
  136. int chkos(os_error *Error) {
  137.   char answer;
  138.  
  139.   if (Error != NULL) {
  140.     fprintf(stderr, "tar: OS error: %s\n", Error->errmess);
  141.     if (!QuietExecution) {
  142.       fprintf(stderr, "tar: continue? ");
  143.       answer = Decision('y');
  144.     }
  145.     if (QuietExecution || answer == 'n' || answer == 'N') {
  146.       Terminate(15);
  147.     }
  148.     return(0);
  149.   }
  150.   return(1);
  151. } /* chkos */
  152.  
  153.  
  154. int ExecuteCommand(char *Template, char *Arg1, char *Arg2, int Warn) {
  155.   char *sp, *dp;
  156.   char OSCommand[256];
  157.  
  158.   dp = OSCommand;
  159.   while (*Template) {
  160.     if (*(Template) != '%')
  161.       *(dp++) = *(Template++);
  162.     else {
  163.       Template++;
  164.       sp = NULL;
  165.       if (*Template == '1')
  166.         sp = Arg1;
  167.       else if (*Template == '2')
  168.         sp = Arg2;
  169.       if (sp == NULL)
  170.         *(dp++) = *(Template - 1);
  171.       else {
  172.         while (*sp)
  173.           *(dp++) = *(sp++);
  174.         Template++;
  175.       }
  176.     }
  177.   }
  178.   *dp = '\0';
  179.   if (system(OSCommand) != 0) {
  180.     if (Warn)
  181.       fprintf(stderr,"Warning: \"%s\" failed.\n",OSCommand);
  182.     return 0;
  183.   }
  184.   return 1;
  185. } /* ExecuteCommand */
  186.  
  187.  
  188. void InterruptHandler(int dummy) {
  189.   signal(SIGINT, SIG_IGN);
  190.   UserInterrupt++;
  191. } /* InterruptHandler */
  192.  
  193.  
  194. void AbortHandler(int dummy) {
  195.   signal(SIGABRT, SIG_IGN);
  196.   UserInterrupt++;
  197. } /* AbortHandler */
  198.  
  199.  
  200. void TerminateHandler(int dummy) {
  201.   signal(SIGTERM, SIG_IGN);
  202.   UserInterrupt++;
  203. } /* TerminateHandler */
  204.  
  205.  
  206. void compress_cleanup(void) {
  207.   remove(ScrapName);
  208.   remove(ScrapNameZ);
  209. } /* compress_cleanup */
  210.  
  211.  
  212. void PrintBlocks(FILE *fd, long blocks) {
  213.   fprintf(fd,"%ld block",blocks);
  214.   if (blocks != 1)
  215.     fputc('s',fd);
  216. } /* PrintBlocks */
  217.  
  218.  
  219. void usage(void) {
  220.   fprintf(stderr,"tar: usage: tar [-]cmd[opt] ARCHIVE [LIST] [BLKS] [-C DIR] file1 file2 ...\n");
  221.   fputs("\
  222. Commands: c          create a new archive\n\
  223.           r          append files to end of archive\n\
  224.           t          list the contents of an archive\n\
  225.           x          extract files from an archive\n\
  226. ",stderr);
  227.   fputs("\
  228. Options:  b BLKS     blocking factor BLKS (block size = BLKS x 512 bytes)\n\
  229.           e LENGTH   maximum length of extension to use in UNIX file names\n\
  230.           f ARCHIVE  read/write archive from file ARCHIVE (mandatory)\n\
  231.           i          ignore checksum errors and zero blocks (normally EOF)\n\
  232.           l [LIST]   read list of files from file LIST or !tarlist as default\n\
  233.           m          do not extract date and times of files\n\
  234.           p          convert '!' in RISC OS names to '_' in UNIX names\n\
  235.           s          swap extension in filename (see documentation)\n\
  236.           v          verbosely list what files we process\n\
  237.           w          ask for confirmation\n\
  238.           z          compress files before archiving\n\
  239.           B          re-block as we read\n\
  240.           C DIR      change to directory DIR\n\
  241.           E          '.' in UNIX names will be converted to '/'\n\
  242.           F          format disc in drive 0 (multiple volumes & E-format only)\n\
  243.           G          use GNU tar multiple volume archiving\n\
  244.           M          use multiple volume archiving\n\
  245.           O          do not ask for confimation to format or write raw discs\n\
  246.           L LEN      maximum file/directory name is LEN when extracting (default 10)\n\
  247.           P          use RISC OS 3 path canonicalise instead of own routine\n\
  248.           Q          quit immediately if error occurs, do not prompt for action\n\
  249.           S          swap extensions in whole path\n\
  250.           T          file types appended to names as with RISC-OS NFS\n\
  251.           U          UNIX archive mode (no Archimedes extensions)\n\
  252.           V          very verbose: also display files that are not extracted\n\
  253.           X          add RISC OS file type as extension to file name in archive\n\
  254.           Z          convert UNIX '.Z' to '/Z' when extracting\n\
  255. Please read the documentation file for further information. I will take no\n\
  256. responsibility for damage or loss of data due to the use of this programme.\n",
  257.  stderr);
  258.   fprintf(stderr,
  259.     "RISC OS tar %s by Frank Lancaster, Copyright (C) 1991-1994.\n", version);
  260.   fprintf(stderr,
  261.     "This programme is public domain. You may not charge anything for it.\n");
  262.   Terminate(16);
  263. } /* usage */
  264.  
  265.  
  266. void ChkScrapName(void) {
  267.   char *cp;
  268.  
  269.   if (ScrapName[0] != '\0')
  270.     return;
  271.   if ((cp = getenv(SCRAP_VAR)) == NULL) {
  272.     fprintf(stderr,"tar: system variable %s not set\n",SCRAP_VAR);
  273.     Terminate(17);
  274.   }
  275.   strcpy(ScrapName,cp);
  276.   strcpy(ScrapNameZ,ScrapName);
  277.   strcat(ScrapNameZ,CompressExt);
  278.   compress_cleanup();
  279. } /* GetScrapName */
  280.  
  281.  
  282. int main(int argc, char *argv[]) {
  283.   char *cp;
  284.  
  285.   if (argc < 2) {
  286.     usage();
  287.   }
  288.  
  289.   argv[argc] = 0;
  290.   argv++;
  291.   for (cp = *argv++; *cp; cp++)
  292.     argv += CheckOption(&cp,*argv);
  293.  
  294. #if WITH_PWD
  295.   if ((InitialUnset = CurrentDirUnset()) == 0) {
  296.     ChangeCurrentDir("\\");
  297.     (void)GetCurrentDir(InitialPreviousDir);
  298.     ChangeCurrentDir("\\");
  299.     (void)GetCurrentDir(InitialCurrentDir);
  300.   }
  301. #endif
  302.  
  303.   GotInitialDirectories = 1;
  304.  
  305.   if ((cp = getenv(TAR_FILETYPE_VAR)) != NULL)
  306.     tarFileType = (int)strtoul(cp,NULL,16);
  307.   else
  308.     tarFileType = 0xC46;
  309.  
  310.   if ((cp = getenv(COMPEXT_VAR)) != NULL)
  311.     strcpy(CompressExt,cp);
  312.   else
  313.     strcpy(CompressExt,"/Z");
  314.   if ((cp = getenv(COMPRESS_VAR)) != NULL)
  315.     strcpy(CompressTemplate,cp);
  316.   else
  317.     strcpy(CompressTemplate,"compress < %1 > %2");
  318.   if ((cp = getenv(DECOMPRESS_VAR)) != NULL)
  319.     strcpy(DecompressTemplate,cp);
  320.   else
  321.     strcpy(DecompressTemplate,"compress -d < %1 > %2");
  322.  
  323.   InitArgs(argv);
  324.   if (!AppendToArchive && !ExtractFromArchive && !ListArchivesContents ||
  325.       AppendToArchive && ExtractFromArchive ||
  326.       ListArchivesContents && ExtractFromArchive ||
  327.       AppendToArchive && ListArchivesContents) {
  328.     usage();
  329.   }
  330.  
  331.   if (CompressFiles) {
  332.     ChkScrapName();
  333.   }
  334.  
  335.   if (ArchiveName == NULL && tapedevice != tapedevice_DISC) {
  336.     fprintf(stderr,"tar: no archive file specified; use 'f' option\n");
  337.     Terminate(18);
  338.   }
  339.  
  340.   TmpBlock = (union HeaderBlock *)malloc(nblock*RECORDSIZE);
  341.   if (TmpBlock == NULL) {
  342.     fprintf(stderr, "tar: blocksize %d too big, can't get memory\n",nblock);
  343.     Terminate(19);
  344.   }
  345.   if (AppendToArchive) {
  346.     if (GetArg(0) == NULL) {
  347.       fprintf(stderr,"tar: error: no files specified\n");
  348.       Terminate(20);
  349.     }
  350.     signal(SIGINT, InterruptHandler);
  351.     signal(SIGABRT, AbortHandler);
  352.     signal(SIGTERM, TerminateHandler);
  353.     if (strcmp(ArchiveName, "-") == 0) {
  354.       if (CreateArchive == 0) {
  355.         fprintf(stderr,"tar: cannot append to standard output archives\n");
  356.         Terminate(21);
  357.       }
  358.       ArchiveIsStdIO = 1;
  359.       ArchiveFD = stdout;
  360.       nblock = 1;
  361.     } else {
  362.       open_writetape();
  363.     }
  364.     ReplaceFiles();
  365.     Terminate(UserInterrupt ? 22 : 0);
  366.   }
  367.   if (strcmp(ArchiveName, "-") == 0) {
  368.     ArchiveIsStdIO = 1;
  369.     ArchiveFD = stdin;
  370.     nblock = 1;
  371.   } else {
  372.     open_readtape();
  373.   }
  374.   if (ExtractFromArchive) {
  375.     ExtractFiles();
  376.   } else {
  377.     ListContents();
  378.   }
  379.   Terminate(UserInterrupt ? 23 : 0);
  380. } /* main */
  381.